const { ObjectId } = require("mongodb");

// 创建文章
async function createArticle(ctx, articleInfo) {
  console.log(articleInfo);

  const currentUserId = new ObjectId(ctx.state.user.sub);
  const categoryId = new ObjectId(articleInfo.categoryId);
  const { title, summary, content } = articleInfo;

  // 封面
  const thumbnail = content.match(/<img\s(.*?)\s?src="(.*?)"/)?.[2];

  // 保存
  const articleColl = ctx.mongoClient.db().collection("articles");
  const result = await articleColl.insertOne({
    ownerId: currentUserId,
    category: categoryId,
    title,
    summary,
    content,
    thumbnail,
    createdAt: new Date(),
    updatedAt: new Date(),
  });

  if (!result.insertedId) {
    return ctx.throw({ code: 10201, message: "创建文章失败" });
  }

  console.log(result);
}

async function getArticleList(ctx, params) {
  const currentUserId = new ObjectId(ctx.state.user.sub);

  const categoryId = params.categoryId;
  const keyword = params.keyword;
  const pageNo = parseInt(params.pageNo) || 1;
  const pageSize = parseInt(params.pageSize) || 10;

  // const filter = {
  //   ownerId: currentUserId,
  // }

  // 准备查询过滤，条件对象
  const filter = {
    ownerId: {
      $eq: currentUserId,
    },
  };

  // 处理条件
  // 1. 传入搜索关键字 则对文章的标题 进行模糊搜索
  if (keyword) {
    filter.title = {
      $regex: new RegExp(keyword, "ig"),
    };
  }
  // 2. 传入分类id 则对文章的分类进行过滤
  if (categoryId) {
    filter.category = {
      $eq: new ObjectId(categoryId),
    };
  }

  const articleColl = ctx.mongoClient.db().collection("articles");
  const total = await articleColl.countDocuments(filter);

  // 使用聚合 对文章表和分类表进行关联查询
  const items = await articleColl
    .aggregate([
      { $match: filter }, // 过滤
      {
        $sort: {
          createdAt: -1, // 按照创建时间降序
        },
      },
      {
        $skip: (pageNo - 1) * pageSize, // 跳过多少条
      },
      {
        $limit: pageSize, // 取多少条
      },
      // 联表查询 根据分类id查
      {
        $lookup: {
          from: "categories", // 关联的表
          localField: "category", // 当前集合的字段
          foreignField: "_id", // 关联字段
          as: "categoryType", // 关联结果存放的字段
        },
      },
      {
        $unwind: "$categoryType", // 展开数组 平铺
      },
      // 去掉不需要的内容
      {
        $project: {
          content: 0, // 不显示文章内容
          summary: 0, // 不显示文章摘要
          ownerId: 0, // 不显示文章作者
        },
      },
    ])
    .toArray();

  return {
    total,
    items,
  };
}

// 异步函数，根据id获取文章
async function getArticleById(ctx, id) {
  console.log(new ObjectId(id));
  // 获取数据库中的articles集合
  const articleColl = ctx.mongoClient.db().collection("articles");
  // 根据id查找文章
  const article = await articleColl.findOne({
    _id: new ObjectId(id),
  });

  // 如果文章不存在，抛出错误
  if (!article) {
    return ctx.throw({ code: 10202, message: "文章不存在" });
  }

  // 返回文章
  return article;
}

async function deleteArticleById(ctx, id) {
  const currentUserId = new ObjectId(ctx.state.user.sub);
  // 获取数据库中的articles集合
  const articleColl = ctx.mongoClient.db().collection("articles");
  // 根据id删除文章
  const result = await articleColl.deleteOne({
    _id: new ObjectId(id),
    ownerId: currentUserId,
  });

  // 如果文章不存在，抛出错误
  if (!result.deletedCount) {
    return ctx.throw({ code: 10202, message: "文章不存在" });
  }
}

async function updateArticle(ctx, id, data) {
  const currentUserId = new ObjectId(ctx.state.user.sub);
  const category = new ObjectId(data.categoryId);
  const { title, content, summary } = data;

  // 封面
  const thumbnail = content.match(/<img\s(.*?)\s?src="(.*?)"/)?.[2]; // 获取第一张图片

  // 获取数据库中的articles集合
  const articleColl = ctx.mongoClient.db().collection("articles");
  // 根据id更新文章
  const result = await articleColl.updateOne(
    {
      _id: new ObjectId(id),
      ownerId: currentUserId,
    },
    {
      $set: {
        category: category,
        title,
        content,
        summary,
        thumbnail,
        updatedAt: new Date(),
      },
    }
  );
}

module.exports = {
  createArticle,
  getArticleList,
  getArticleById,
  deleteArticleById,
  updateArticle,
};
